/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package org.apache.guacamole.vault.ksm.conf;

import com.google.inject.Inject;
import com.google.inject.Singleton;
import org.apache.guacamole.GuacamoleException;
import org.apache.guacamole.environment.Environment;
import org.apache.guacamole.properties.BooleanGuacamoleProperty;
import org.apache.guacamole.vault.conf.VaultConfigurationService;
import com.keepersecurity.secretsManager.core.SecretsManagerOptions;

/**
 * Service for retrieving configuration information regarding the Keeper
 * Secrets Manager authentication extension.
 */
@Singleton
public class KsmConfigurationService extends VaultConfigurationService {

    /**
     * The Guacamole server environment.
     */
    @Inject
    private Environment environment;

    /**
     * The name of the file which contains the YAML mapping of connection
     * parameter token to secrets within Keeper Secrets Manager.
     */
    private static final String TOKEN_MAPPING_FILENAME = "ksm-token-mapping.yml";

    /**
     * The name of the properties file containing Guacamole configuration
     * properties whose values are the names of corresponding secrets within
     * Keeper Secrets Manager.
     */
    private static final String PROPERTIES_FILENAME = "guacamole.properties.ksm";

    /**
     * The base64-encoded configuration information generated by the Keeper
     * Commander CLI tool.
     */
    private static final KsmConfigProperty KSM_CONFIG = new KsmConfigProperty() {

        @Override
        public String getName() {
            return "ksm-config";
        }
    };

    /**
     * Whether unverified server certificates should be accepted.
     */
    private static final BooleanGuacamoleProperty ALLOW_UNVERIFIED_CERT = new BooleanGuacamoleProperty() {

        @Override
        public String getName() {
            return "ksm-allow-unverified-cert";
        }
    };

    /**
     * Creates a new KsmConfigurationService which reads the configuration
     * from "ksm-token-mapping.yml" and properties from
     * "guacamole.properties.ksm". The token mapping is a YAML file which lists
     * each connection parameter token and the name of the secret from which
     * the value for that token should be read, while the properties file is an
     * alternative to guacamole.properties where each property value is the
     * name of a secret containing the actual value.
     */
    public KsmConfigurationService() {
        super(TOKEN_MAPPING_FILENAME, PROPERTIES_FILENAME);
    }

    /**
     * Return whether unverified server certificates should be accepted when
     * communicating with Keeper Secrets Manager.
     *
     * @return
     *     true if unverified server certificates should be accepted, false
     *     otherwise.
     *
     * @throws GuacamoleException
     *     If the value specified within guacamole.properties cannot be
     *     parsed.
     */
    public boolean getAllowUnverifiedCertificate() throws GuacamoleException {
        return environment.getProperty(ALLOW_UNVERIFIED_CERT, false);
    }

    /**
     * Returns the options required to authenticate with Keeper Secrets Manager
     * when retrieving secrets. These options are read from the contents of
     * base64-encoded JSON configuration data generated by the Keeper Commander
     * CLI tool.
     *
     * @return
     *     The options that should be used when connecting to Keeper Secrets
     *     Manager when retrieving secrets.
     *
     * @throws GuacamoleException
     *     If required properties are not specified within
     *     guacamole.properties or cannot be parsed.
     */
    public SecretsManagerOptions getSecretsManagerOptions() throws GuacamoleException {
        return new SecretsManagerOptions(environment.getRequiredProperty(KSM_CONFIG), null,
                getAllowUnverifiedCertificate());
    }
}
